<script setup lang="ts">
import { computed, reactive, ref } from "vue";
import { ElMessage } from "element-plus";
import type { FormInstance, FormRules } from "element-plus";
import type { ConfigCreatePayload, ConfigItem } from "@/api/system/config";

const VALUE_TYPE_OPTIONS: Array<{
  label: string;
  value: ConfigItem["value_type"];
}> = [
  { label: "字符串", value: "string" },
  { label: "JSON", value: "json" },
  { label: "布尔", value: "bool" },
  { label: "整数", value: "int" },
  { label: "小数", value: "decimal" },
  { label: "浮点数", value: "float" }
];

interface Props {
  categories: string[];
  onSubmit: (payload: ConfigCreatePayload) => Promise<void>;
}

const props = defineProps<Props>();

const formRef = ref<FormInstance>();

const formModel = reactive({
  config_key: "",
  value_type: "string" as ConfigItem["value_type"],
  config_value: "",
  config_value_bool: true,
  category: "",
  status: 1,
  description: ""
});

const isBooleanType = computed(() => formModel.value_type === "bool");
const isJsonType = computed(() => formModel.value_type === "json");

const rules: FormRules<typeof formModel> = {
  config_key: [{ required: true, message: "请输入配置键", trigger: "blur" }],
  value_type: [
    { required: true, message: "请选择配置类型", trigger: "change" }
  ],
  config_value: [
    {
      validator: (_rule, value, callback) => {
        if (isBooleanType.value) {
          callback();
          return;
        }
        if (value === "" || value === null || value === undefined) {
          callback(new Error("请填写配置值"));
          return;
        }
        callback();
      },
      trigger: ["blur", "change"]
    }
  ]
};

const resetValueByType = () => {
  if (isBooleanType.value) {
    formModel.config_value_bool = true;
  } else if (isJsonType.value) {
    formModel.config_value = "{}";
  } else {
    formModel.config_value = "";
  }
};

const handleTypeChange = () => {
  resetValueByType();
};

const parseValue = (): ConfigCreatePayload["config_value"] => {
  const raw = formModel.config_value;
  switch (formModel.value_type) {
    case "bool":
      return Boolean(formModel.config_value_bool);
    case "int":
      if (raw === "" || raw === null || raw === undefined) {
        throw new Error("请输入数值");
      }
      if (Number.isNaN(Number(raw))) {
        throw new Error("整数格式不正确");
      }
      return Number.parseInt(String(raw), 10);
    case "decimal":
    case "float":
      if (raw === "" || raw === null || raw === undefined) {
        throw new Error("请输入数值");
      }
      if (Number.isNaN(Number(raw))) {
        throw new Error("数值格式不正确");
      }
      return Number(raw);
    case "json":
      try {
        return raw ? JSON.parse(String(raw)) : {};
      } catch (error) {
        throw new Error("JSON 格式不正确");
      }
    default:
      return raw;
  }
};

const submitForm = async () => {
  try {
    await formRef.value?.validate();
  } catch {
    return false;
  }

  let parsed: ConfigCreatePayload["config_value"];
  try {
    parsed = parseValue();
  } catch (error: any) {
    ElMessage.error(error?.message ?? "配置值格式不正确");
    return false;
  }

  const payload: ConfigCreatePayload = {
    config_key: formModel.config_key.trim(),
    value_type: formModel.value_type,
    config_value: parsed,
    category: formModel.category.trim() || undefined,
    status: formModel.status,
    description: formModel.description.trim() || undefined
  };

  try {
    await props.onSubmit(payload);
    return true;
  } catch {
    return false;
  }
};

defineExpose({ submitForm, handleTypeChange });
</script>

<template>
  <el-form ref="formRef" :model="formModel" :rules="rules" label-width="100px">
    <el-form-item label="配置键" prop="config_key">
      <el-input
        v-model.trim="formModel.config_key"
        placeholder="请输入唯一配置键"
        autocomplete="off"
      />
    </el-form-item>
    <el-form-item label="配置类型" prop="value_type">
      <el-select
        v-model="formModel.value_type"
        placeholder="请选择类型"
        class="w-full"
        @change="handleTypeChange"
      >
        <el-option
          v-for="item in VALUE_TYPE_OPTIONS"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
    </el-form-item>
    <el-form-item
      :label="isBooleanType ? '开启' : '配置值'"
      :prop="isBooleanType ? 'config_value_bool' : 'config_value'"
    >
      <el-switch
        v-if="isBooleanType"
        v-model="formModel.config_value_bool"
        active-text="是"
        inactive-text="否"
      />
      <el-input
        v-else
        v-model="formModel.config_value"
        :type="isJsonType ? 'textarea' : 'text'"
        :rows="isJsonType ? 6 : 1"
        placeholder="请输入配置值"
      />
    </el-form-item>
    <el-form-item label="分类">
      <el-select
        v-model="formModel.category"
        class="w-full"
        filterable
        allow-create
        default-first-option
        placeholder="请选择或输入分类"
      >
        <el-option
          v-for="item in props.categories"
          :key="item"
          :label="item"
          :value="item"
        />
      </el-select>
    </el-form-item>
    <el-form-item label="状态">
      <el-switch
        v-model="formModel.status"
        :inactive-value="0"
        :active-value="1"
      />
    </el-form-item>
    <el-form-item label="描述">
      <el-input
        v-model="formModel.description"
        type="textarea"
        :rows="3"
        maxlength="200"
        show-word-limit
        placeholder="配置用途或备注"
      />
    </el-form-item>
  </el-form>
</template>
